/**
 *******************************************************************************
 * @FileName  : l2cap_api.h
 * @Author    : GaoQiu
 * @CreateDate: 2020-02-18
 * @Copyright : Copyright(C) GaoQiu
 *              All Rights Reserved.
 *******************************************************************************
 *
 * The information contained herein is confidential and proprietary property of
 * GaoQiu and is available under the terms of Commercial License Agreement
 * between GaoQiu and the licensee in separate contract or the terms described
 * here-in.
 *
 * This heading MUST NOT be removed from this file.
 *
 * Licensees are granted free, non-transferable use of the information in this
 * file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
 *
 *******************************************************************************
 */

#ifndef L2CAP_API_H_
#define L2CAP_API_H_

#include "stack/ble_types.h"
#include "utils/mdc.h"
#include "l2cap_defs.h"

/*! 4B(HCI head) + 4B(l2cap head) + mtu(user ATT_MTU) + 8B(Msg queue head) */
#define L2C_BUF_SIZE(mtu)                  (4 + 4 + (mtu) + 8)

/*!  Invalid channel registration ID for connection oriented channels */
#define L2CAP_COC_REG_ID_NONE               0

/*!  Invalid channel ID for connection oriented channels */
#define L2CAP_COC_CID_NONE                  0

/**
 * Name L2CAP COC Channel Roles
 * 		Connection oriented channel initiator/acceptor role
 * @{
 */
#define L2CAP_COC_ROLE_NONE                 0x00      /*!< No role (unallocated) */
#define L2CAP_COC_ROLE_INITIATOR            0x01      /*!< Channel initiator */
#define L2CAP_COC_ROLE_ACCEPTOR             0x02      /*!< Channel acceptor */
/**@}*/

/*! L2CAP Event define. */
enum{
	L2C_EVT_COC_CONN_IND,
	L2C_EVT_COC_DISCON_IND,
	L2C_EVT_COC_DATA_RX_IND,
	L2C_EVT_COC_DATA_CFM_IND,
};

/*!  Connection oriented channel service ID */
typedef uint16_t L2cCocServiceId_t;

/*!  Connection oriented channel registration(service) structure */
typedef struct{
	uint16_t        	psm;              /*!< Protocol service multiplexer */
	uint16_t       		mps;              /*!< Maximum receive PDU fragment size */
	uint16_t       	    mtu;              /*!< Maximum receive data packet size */
	uint16_t       		credits;          /*!< Data packet receive credits for this channel */
	bool_t          	authoriz;         /*!< TRUE if authorization is required */
	uint8_t         	secLevel;         /*!< Channel minimum security level requirements */
	//uint8_t         	role;             /*!< Channel initiator/acceptor role */
} L2cCocService_t;

/*! L2cap channel pair. */
typedef struct{
	uint16_t scid;
	uint16_t dcid;
}L2cChanPair_t;

/*! L2cap connection parameter update indication structure. */
typedef struct{
	MdcMsgHdr_t  hdr;
	uint16_t     intervalMin;
	uint16_t     intervalMax;
	uint16_t     latency;
	uint16_t     timeout;
	uint16_t     accepted;         /*!< use for l2cap slave. */
}L2cConnParamUpdInd_t;

/*! Connection oriented channel connect indication structure. */
typedef struct{
	MdcMsgHdr_t           hdr;              /*!< Header structure */
	uint16_t              psm;              /*!< Connected PSM */
	uint16_t              peerMtu;          /*!< Data packet MTU peer can receive. */
	L2cChanPair_t         chnPair[5];       /*!< local-peer channel ID pair. */
} L2cCocConnectInd_t;

/*! Connection oriented channel disconnect indication structure.*/
typedef struct{
	MdcMsgHdr_t           hdr;              /*!< Header structure */
	L2cChanPair_t         chnPair;          /*!< Local channel ID */
	uint16_t              result;           /*!< Connection failure result code */
} L2cCocDisconnectInd_t;

/*! Connection oriented channel data indication structure. */
typedef struct{
	MdcMsgHdr_t           hdr;              /*!< Header structure */
	uint16_t              cid;              /*!< Local channel ID */
	uint8_t              *pData;            /*!< Pointer to packet data */
	uint16_t              dataLen;          /*!< packet data length */
} L2cCocDataInd_t;

/*! Connection oriented channel disconnect indication structure. */
typedef struct{
	MdcMsgHdr_t           hdr;              /*!< Header structure */
	uint16_t              cid;              /*!< Local channel ID */
} L2cCocDataCnf_t;

/*
 * @brief Connection oriented channel event structure
 *
 * Connection oriented channel callback header parameters:
 *
 * @param hdr.event     Callback event
 * @param hdr.param     DM connection ID
 * @param hdr.status    Event status (L2C_COC_DATA_CNF only)
 */
typedef union{
	MdcMsgHdr_t             hdr;              /*!< Header structure */
	L2cCocConnectInd_t      connectInd;       /*!< Channel connect indication */
	L2cCocDisconnectInd_t   disconnectInd;    /*!< Channel disconnect indication */
	L2cCocDataInd_t         dataInd;          /*!< Received data indication */
	L2cCocDataCnf_t         dataCnf;          /*!< Transmit data confirm */
}L2cCocEvt_t;

typedef void (*L2cCocCback_t)(L2cCocEvt_t *pMsg);

/*!   L2CAP common data handler call-back. */
typedef void (*L2cDataHanderCback_t)(uint16_t connHandle, uint8_t *pPacket, uint32_t len);

void L2C_Init(void);
void L2C_MstInit(void);
void L2C_SlvInit(void);

void L2C_RegisterDataHandler(uint16_t cid, L2cDataHanderCback_t func);

BleState_t L2C_SlvConnUpdateReq(uint16_t connHandle, uint16_t minInterval, uint16_t maxInterval,
		                        uint16_t slaveLatency, uint16_t timeout);

L2cCocServiceId_t L2C_CocRegisterService(L2cCocService_t *pService, L2cCocCback_t cback);
int L2C_CocCreateLeChannel(uint16_t connHandle, uint16_t psm);
int L2C_CocCreateChannel(uint16_t connHandle, uint16_t psm, uint16_t chnNum);
int L2C_CocDisconnChannel(uint16_t connHandle, uint16_t dcid, uint16_t scid);

#endif /* L2CAP_API_H_ */
